namespace PayPal.Platform.SDK
{
    using System;
    using PayPal.AdaptivePayments;

    /// <summary>
    /// AdapativePayments Wrapper class
    /// </summary>
    public class AdapativePayments : CallerServices
    {
        private const string ApEndpoint = "AdaptivePayments/";
        private string result = string.Empty;
        private TransactionException lastError = null;
        private object res = string.Empty;

        /// <summary>
        /// Returns "SUCCESS" if API request retuns Success response, else returns "FAILURE"
        /// </summary>
        public string IsSuccess
        {
            get
            {
                return this.result;
            }
        }

        /// <summary>
        /// LastError
        /// </summary>
        public TransactionException LastError
        {
            get
            {
                return this.lastError;
            }
        }

        /// <summary>
        /// LastResponse
        /// </summary>
        public string LastResponse
        {
            get
            {
                return this.res.ToString();
            }
        }

        /// <summary>
        /// Calls Pay Platform API for the given PayRequest and returns PayResponse 
        /// </summary>
        /// <param name="request">PayRequest</param>
        /// <returns>PayResponse</returns>
        public PayResponse Pay(PayRequest request)
        {
            PayResponse response = null;
            PayLoad = null;

            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "Pay";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }
                
                this.res = this.CallAPI();

                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PayResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.PayResponse))
                    {
                        response = (PayPal.AdaptivePayments.PayResponse)obj;
                    }

                    string name = Enum.GetName(response.responseEnvelope.ack.GetType(), response.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";

                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        response = (PayPal.AdaptivePayments.PayResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PayResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        response = (PayPal.AdaptivePayments.PayResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PayResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PayResponse));
                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.PayResponse))
                        {
                            response = (PayPal.AdaptivePayments.PayResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments ->  method.", ex);
            }

            return response;
        }

        /// <summary>
        /// Calls Pay Platform API for the given PayRequest and returns SePayOptionsResponse 
        /// </summary>
        /// <param name="request">PayRequest</param>
        /// <returns>PayResponse</returns>
        public SetPaymentOptionsResponse SetPaymentOptions(SetPaymentOptionsRequest request)
        {
            SetPaymentOptionsResponse response = null;
            PayLoad = null;

            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "SetPaymentOptions";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();

                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.SetPaymentOptionsResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.SetPaymentOptionsResponse))
                    {
                        response = (PayPal.AdaptivePayments.SetPaymentOptionsResponse)obj;
                    }

                    string name = Enum.GetName(response.responseEnvelope.ack.GetType(), response.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";

                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        response = (PayPal.AdaptivePayments.SetPaymentOptionsResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.SetPaymentOptionsResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        response = (PayPal.AdaptivePayments.SetPaymentOptionsResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.SetPaymentOptionsResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.SetPaymentOptionsResponse));
                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.SetPaymentOptionsResponse))
                        {
                            response = (PayPal.AdaptivePayments.SetPaymentOptionsResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments ->  method.", ex);
            }

            return response;
        }
        
        /// <summary>
        /// Calls Pay Platform API for the given SetPaymentOptions and returns PayOptionsResponse 
        /// </summary>
        /// <param name="request">PayRequest</param>
        /// <returns>PayResponse</returns>
        public GetPaymentOptionsResponse GetPaymentOptions(GetPaymentOptionsRequest request)
        {
            GetPaymentOptionsResponse gpResponse = null;
            PayLoad = null;

            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "GetPaymentOptions";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();

                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.GetPaymentOptionsResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.GetPaymentOptionsResponse))
                    {
                        gpResponse = (PayPal.AdaptivePayments.GetPaymentOptionsResponse)obj;
                    }

                    string name = Enum.GetName(gpResponse.responseEnvelope.ack.GetType(), gpResponse.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";

                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        gpResponse = (PayPal.AdaptivePayments.GetPaymentOptionsResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.GetPaymentOptionsResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        gpResponse = (PayPal.AdaptivePayments.GetPaymentOptionsResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.GetPaymentOptionsResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.GetPaymentOptionsResponse));
                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.GetPaymentOptionsResponse))
                        {
                            gpResponse = (PayPal.AdaptivePayments.GetPaymentOptionsResponse)obj;
                        }
                    }
                    
                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments ->  method.", ex);
            }

            return gpResponse;
        }
        
        /// <summary>
        /// Calls Pay Platform API for the given ExecutePayment and returns PayOptionsResponse 
        /// </summary>
        /// <param name="request">PayRequest</param>
        /// <returns>PayResponse</returns>
        public ExecutePaymentResponse ExecutePayment(ExecutePaymentRequest request)
        {
             ExecutePaymentResponse epResponse = null;
             PayLoad = null;

             try
             {
                 APIProfile.EndPointAppend = ApEndpoint + "ExecutePayment";
                 if (APIProfile.RequestDataformat == "SOAP11")
                 {
                     PayLoad = SoapEncoder.Encode(request);
                 }
                 else if (APIProfile.RequestDataformat == "XML")
                 {
                     PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                 }
                 else
                 {
                     PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                 }

                 this.res = CallAPI();

                 if (APIProfile.RequestDataformat == "JSON")
                 {
                     object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ExecutePaymentResponse));
                     if (obj.GetType() == typeof(PayPal.AdaptivePayments.ExecutePaymentResponse))
                     {
                         epResponse = (PayPal.AdaptivePayments.ExecutePaymentResponse)obj;
                     }

                     string name = Enum.GetName(epResponse.responseEnvelope.ack.GetType(), epResponse.responseEnvelope.ack);

                     if (name == "Failure")
                     {
                         this.result = "FAILURE";
                         TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                         this.lastError = tranactionEx;
                     }
                 }
                 else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                 {
                     this.result = "FAILURE";

                     if (APIProfile.RequestDataformat == "SOAP11")
                     {
                         TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                         this.lastError = tranactionEx;
                     }
                     else if (APIProfile.RequestDataformat == "XML")
                     {
                         TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                         this.lastError = tranactionEx;
                     }
                     else
                     {
                         TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                         this.lastError = tranactionEx;
                     }
                 }
                 else
                 {
                     if (APIProfile.RequestDataformat == "SOAP11")
                     {
                         epResponse = (PayPal.AdaptivePayments.ExecutePaymentResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ExecutePaymentResponse));
                     }
                     else if (APIProfile.RequestDataformat == "XML")
                     {
                         epResponse = (PayPal.AdaptivePayments.ExecutePaymentResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ExecutePaymentResponse));
                     }
                     else
                     {
                         object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ExecutePaymentResponse));
                         if (obj.GetType() == typeof(PayPal.AdaptivePayments.ExecutePaymentResponse))
                         {
                             epResponse = (PayPal.AdaptivePayments.ExecutePaymentResponse)obj;
                         }
                     }

                     this.result = "SUCCESS";
                 }
             }
             catch (FATALException)
             {
                 throw;
             }
             catch (Exception ex)
             {
                 throw new FATALException("Error occurred in AdapativePayments ->  method.", ex);
             }
            
             return epResponse;
        }

        /// <summary>
        /// TCalls PreapprovalDetails Platform API for the given PreapprovalDetailsRequest and returns PreapprovalDetailsResponse
        /// </summary>
        /// <param name="request">PreapprovalDetailsRequest</param>
        /// <returns>PreapprovalDetailsResponse</returns>
        public PreapprovalDetailsResponse PreapprovalDetails(PreapprovalDetailsRequest request)
        {
            PreapprovalDetailsResponse pdResponse = null;
            PayLoad = null;
            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "PreapprovalDetails";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();
                
                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalDetailsResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.PreapprovalDetailsResponse))
                    {
                        pdResponse = (PayPal.AdaptivePayments.PreapprovalDetailsResponse)obj;
                    }

                    string name = Enum.GetName(pdResponse.responseEnvelope.ack.GetType(), pdResponse.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        pdResponse = (PayPal.AdaptivePayments.PreapprovalDetailsResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalDetailsResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        pdResponse = (PayPal.AdaptivePayments.PreapprovalDetailsResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalDetailsResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalDetailsResponse));

                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.PreapprovalDetailsResponse))
                        {
                            pdResponse = (PayPal.AdaptivePayments.PreapprovalDetailsResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments -> PreapprovalDetails method.", ex);
            }

            return pdResponse;
        }
        
        /// <summary>
        /// Calls Refund Platform API for the given RefundRequest and returns RefundResponse
        /// </summary>
        /// <param name="request">RefundRequest</param>
        /// <returns>RefundResponse</returns>
        public RefundResponse Refund(RefundRequest request)
        {
            RefundResponse response = null;
            PayLoad = null;
            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "Refund";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();
                
                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.RefundResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.RefundResponse))
                    {
                        response = (PayPal.AdaptivePayments.RefundResponse)obj;
                    }

                    string name = Enum.GetName(response.responseEnvelope.ack.GetType(), response.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        response = (PayPal.AdaptivePayments.RefundResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.RefundResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        response = (PayPal.AdaptivePayments.RefundResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.RefundResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.RefundResponse));

                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.RefundResponse))
                        {
                            response = (PayPal.AdaptivePayments.RefundResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments -> Refund method.", ex);
            }

            return response;
        }
        
        /// <summary>
        /// Calls PaymentDetails Platform API for the given PaymentDetailsRequest and returns PaymentDetailsResponse
        /// </summary>
        /// <param name="request">PaymentDetailsRequest</param>
        /// <returns>PaymentDetailsResponse</returns>
        public PaymentDetailsResponse PaymentDetails(PaymentDetailsRequest request)
        {
            PaymentDetailsResponse response = null;
            PayLoad = null;
            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "PaymentDetails";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();
                
                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PaymentDetailsResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.PaymentDetailsResponse))
                    {
                        response = (PayPal.AdaptivePayments.PaymentDetailsResponse)obj;
                    }

                    string name = Enum.GetName(response.responseEnvelope.ack.GetType(), response.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        response = (PayPal.AdaptivePayments.PaymentDetailsResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PaymentDetailsResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        response = (PayPal.AdaptivePayments.PaymentDetailsResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PaymentDetailsResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PaymentDetailsResponse));
                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.PaymentDetailsResponse))
                        {
                            response = (PayPal.AdaptivePayments.PaymentDetailsResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments -> PaymentDetails method.", ex);
            }

            return response;
        }
        
        /// <summary>
        /// Calls Preapproval Platform API for the given PreapprovalRequest and returns PreapprovalResponse
        /// </summary>
        /// <param name="request">PreapprovalRequest</param>
        /// <returns>PreapprovalResponse</returns>
        public PreapprovalResponse Preapproval(PreapprovalRequest request)
        {
            PreapprovalResponse response = null;
            PayLoad = null;
            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "Preapproval";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();
                
                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.PreapprovalResponse))
                    {
                        response = (PayPal.AdaptivePayments.PreapprovalResponse)obj;
                    }

                    string name = Enum.GetName(response.responseEnvelope.ack.GetType(), response.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        response = (PayPal.AdaptivePayments.PreapprovalResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        response = (PayPal.AdaptivePayments.PreapprovalResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.PreapprovalResponse));

                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.PreapprovalResponse))
                        {
                            response = (PayPal.AdaptivePayments.PreapprovalResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments -> Preapproval method.", ex);
            }

            return response;
        }
        
        /// <summary>
        /// Calls CancelPreapproval Platform API for the given CancelPreapprovalRequest and returns CancelPreapprovalResponse
        /// </summary>
        /// <param name="request">CancelPreapprovalRequest</param>
        /// <returns>CancelPreapprovalResponse</returns>
        public CancelPreapprovalResponse CancelPreapproval(CancelPreapprovalRequest request)
        {
            CancelPreapprovalResponse cpResponse = null;
            PayLoad = null;
            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "CancelPreapproval";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();
                
                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.CancelPreapprovalResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.CancelPreapprovalResponse))
                    {
                        cpResponse = (PayPal.AdaptivePayments.CancelPreapprovalResponse)obj;
                    }

                    string name = Enum.GetName(cpResponse.responseEnvelope.ack.GetType(), cpResponse.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        cpResponse = (PayPal.AdaptivePayments.CancelPreapprovalResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.CancelPreapprovalResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        cpResponse = (PayPal.AdaptivePayments.CancelPreapprovalResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.CancelPreapprovalResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.CancelPreapprovalResponse));

                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.CancelPreapprovalResponse))
                        {
                            cpResponse = (PayPal.AdaptivePayments.CancelPreapprovalResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments -> CancelPreapproval method.", ex);
            }

            return cpResponse;
        }

        /// <summary>
        /// Calls ConvertCurrency Platform API for the given ConvertCurrencyRequest and returns ConvertCurrencyResponse
        /// </summary>
        /// <param name="request">ConvertCurrencyRequest</param>
        /// <returns>ConvertCurrencyResponse</returns>
        public ConvertCurrencyResponse ConvertCurrency(ConvertCurrencyRequest request)
        {
            ConvertCurrencyResponse ccResponse = null;
            PayLoad = null;
            try
            {
                APIProfile.EndPointAppend = ApEndpoint + "ConvertCurrency";
                if (APIProfile.RequestDataformat == "SOAP11")
                {
                    PayLoad = SoapEncoder.Encode(request);
                }
                else if (APIProfile.RequestDataformat == "XML")
                {
                    PayLoad = PayPal.Platform.SDK.XMLEncoder.Encode(request);
                }
                else
                {
                    PayLoad = PayPal.Platform.SDK.JSONSerializer.ToJavaScriptObjectNotation(request);
                }

                this.res = CallAPI();

                if (APIProfile.RequestDataformat == "JSON")
                {
                    object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ConvertCurrencyResponse));
                    if (obj.GetType() == typeof(PayPal.AdaptivePayments.ConvertCurrencyResponse))
                    {
                        ccResponse = (PayPal.AdaptivePayments.ConvertCurrencyResponse)obj;
                    }

                    string name = Enum.GetName(ccResponse.responseEnvelope.ack.GetType(), ccResponse.responseEnvelope.ack);

                    if (name == "Failure")
                    {
                        this.result = "FAILURE";
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else if (this.res.ToString().ToUpper().Replace("<ACK>FAILURE</ACK>", string.Empty).Length != this.res.ToString().Length)
                {
                    this.result = "FAILURE";
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.SOAP11, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.XML, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                    else
                    {
                        TransactionException tranactionEx = new TransactionException(PayLoadFromat.JSON, this.res.ToString());
                        this.lastError = tranactionEx;
                    }
                }
                else
                {
                    if (APIProfile.RequestDataformat == "SOAP11")
                    {
                        ccResponse = (PayPal.AdaptivePayments.ConvertCurrencyResponse)SoapEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ConvertCurrencyResponse));
                    }
                    else if (APIProfile.RequestDataformat == "XML")
                    {
                        ccResponse = (PayPal.AdaptivePayments.ConvertCurrencyResponse)XMLEncoder.Decode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ConvertCurrencyResponse));
                    }
                    else
                    {
                        object obj = JSONSerializer.JsonDecode(this.res.ToString(), typeof(PayPal.AdaptivePayments.ConvertCurrencyResponse));

                        if (obj.GetType() == typeof(PayPal.AdaptivePayments.ConvertCurrencyResponse))
                        {
                            ccResponse = (PayPal.AdaptivePayments.ConvertCurrencyResponse)obj;
                        }
                    }

                    this.result = "SUCCESS";
                }
            }
            catch (FATALException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new FATALException("Error occurred in AdapativePayments -> ConvertCurrency method.", ex);
            }

            return ccResponse;
        }
    }
}
